//
//  SEChatViewController+Delegate.swift
//  SmartEyeForPatient
//
//  Created by QDSG on 2021/4/26.
//

import UIKit
import Photos

// MARK: - UIGestureRecognizerDelegate

extension SEChatViewController: UIGestureRecognizerDelegate {
    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
        // 弹出键盘后，避免按钮的点击事件被tableView的手势拦截而不执行，例如播放语音
        if touch.view is UIButton {
            return false
        }
        return true
    }
}

// MARK: - SEVoiceRecordDelegate

extension SEChatViewController: SEVoiceRecordDelegate {
    func voiceRecordUpdateMetra(_ metra: Float) {
        voiceIndicatorView.updateMetersValue(metra)
    }
    
    func voiceRecordTooShort() {
        voiceIndicatorView.voiceTooShort()
    }
    
    func voiceRecordFailed() {
        SEHUD.showError(message: "录音失败，请重试...")
    }
    
    func voiceRecordFinished(_ uploadAmrData: Data, recordTime: Float, fileHash: String) {
        voiceIndicatorView.endRecord()
        
        // TODO: 上传音频
    }
}

// MARK: - UITableViewDataSource

extension SEChatViewController: UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return viewModel.numberOfRows
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let vm = viewModel.viewMode(at: indexPath)
        switch vm.messageType {
        case .start, .end:
            let cell = tableView.dequeueReusableCell(withIdentifier: SEChatStartEndCell.reuseIdentifier(),
                                                     for: indexPath) as! SEChatStartEndCell
            cell.update(with: vm)
            return cell
        case .text, .videoCall:
            let cell = tableView.dequeueReusableCell(withIdentifier: SEChatTextCell.reuseIdentifier(),
                                                     for: indexPath) as! SEChatTextCell
            cell.delegate = self
            cell.update(with: vm)
            return cell
        case .image:
            let cell = tableView.dequeueReusableCell(withIdentifier: SEChatImageCell.reuseIdentifier(),
                                                     for: indexPath) as! SEChatImageCell
            cell.delegate = self
            cell.update(with: vm)
            return cell
        case .time:
            let cell = tableView.dequeueReusableCell(withIdentifier: SEChatTimeCell.reuseIdentifier(),
                                                     for: indexPath) as! SEChatTimeCell
            cell.update(with: vm)
            return cell
        case .endInquiry:
            let cell = tableView.dequeueReusableCell(withIdentifier: SEChatConfirmEndCell.reuseIdentifier(),
                                                     for: indexPath) as! SEChatConfirmEndCell
            cell.delegate = self
            cell.update(with: vm)
            return cell
        case .prescription:
            let cell = tableView.dequeueReusableCell(withIdentifier: SEChatPrescriptionCell.reuseIdentifier(),
                                                     for: indexPath) as! SEChatPrescriptionCell
            cell.delegate = self
            cell.update(with: vm)
            return cell
        case .checkReport:
            let cell = tableView.dequeueReusableCell(withIdentifier: SEChatCheckReportCell.reuseIdentifier(),
                                                     for: indexPath) as! SEChatCheckReportCell
            cell.update(with: vm)
            return cell
        case .fileAuthorize:
            let cell = tableView.dequeueReusableCell(withIdentifier: SEChatFileAuthorizeCell.reuseIdentifier(), for: indexPath) as! SEChatFileAuthorizeCell
            cell.delegate = self
            cell.update(with: vm)
            return cell
        default:
            return SEChatBaseCell()
        }
    }
}

extension SEChatViewController: UITableViewDelegate {
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        let vm = viewModel.viewMode(at: indexPath)
        return vm.cellHeight
    }
    
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        tableView.deselectRow(at: indexPath, animated: true)
        
        let vm = viewModel.viewMode(at: indexPath)
        
        switch vm.messageType {
        case .prescription:
            if vm.chatRecord.prescription?.status != .noDrug {
                pushToPrescriptionDetail(vm)
            }
        case .checkReport:
            pushToCheckReport(vm)
        default:
            break
        }
    }
    
    private func pushToPrescriptionDetail(_ viewModel: SEChatViewModel) {
        let vc = SEPrescriptionOrderDetailViewController(prescriptionId: viewModel.chatRecord.prescription?.id ?? "")
        vc.title = "处方详情"
        navigationController?.pushViewController(vc, animated: true)
    }
    
    private func pushToCheckReport(_ viewModel: SEChatViewModel) {
        guard let id = viewModel.checkReport?.id,
              let hospitalId = viewModel.checkReport?.checkHosId,
              let status = viewModel.checkReport?.status else {
            SEHUD.show(in: view, message: "该眼科检查AI报告存在问题!", position: .center)
            return
        }

        let url = URL(string: SEApiManager.examineAIReportUrl(applyFormId: id,
                                                              hospitalId: hospitalId,
                                                              status: status))
        let vc = SEWebViewController(url: url, title: viewModel.checkReport?.reportTitle ?? "检查报告")
        navigationController?.pushViewController(vc, animated: true)
    }
}

// MARK: - SEChatCellDelegate

extension SEChatViewController: SEChatCellDelegate {
    func imageCell(_ cell: SEChatImageCell, didTappedImageViewWith viewModel: SEChatViewModel?) {
        presentImageBrowser(imageView: cell.chatImageView, originalUrl: viewModel?.chatRecord.url)
    }
    
    func confirmEndCell(_ cell: SEChatConfirmEndCell, confirmEndInquiry end: Bool) {
        let indexPath = msgTableView.indexPath(for: cell)
        
        let dealStatus: SEInquiryChangeStatus = end ? .confirmEnd : .rejectEnd
        viewModel.changeOnlineInquiryStatus(dealStatus, at: indexPath)
    }
    
    func prescriptionCell(_ cell: SEChatPrescriptionCell, didTappedPay viewModel: SEChatViewModel?) {
        guard let vm = viewModel else { return }
        pushToPrescriptionDetail(vm)
    }
    
    func cellResendTapped(_ cell: SEChatBaseCell) {
        guard let indexPath = msgTableView.indexPath(for: cell) else { return }
        
        let vm = viewModel.viewMode(at: indexPath)
        vm.chatRecord.messageSendStatus = .sending
        msgTableView.reloadRows(at: [indexPath], with: .none)
        
        SEIMManager.shared.sendMessage(vm.chatRecord)
    }
    
    func fileAuthorizeCell(_ cell: SEChatFileAuthorizeCell, didTappedWithStatus status: SEPatientFileAuthorizedStatus) {
        guard let indexPath = msgTableView.indexPath(for: cell) else { return }
        
        viewModel.updateFileAuthorizationStatus(status, at: indexPath)
    }
}

// MARK: - SEChatMoreViewDelegate

extension SEChatViewController: SEChatMoreViewDelegate {
    func chatMoreView(_ moreView: SEChatMoreView, didClickedItemType itemType: SEChatMoreItem.ItemType) {
        hideAllKeyboard()
        switch itemType {
        case .photo:
            guard !isImageUploading else {
                SEHUD.show(in: view, message: "正在上传图片...", position: .top)
                return
            }
            SEAlert.showImagePickerSheet(in: self) { _ in
                self.checkCameraPermission()
            } photoHandler: { _ in
                self.openPhotoLibrary()
            }
        case .video:
//            checkCameraPermission()
            break
        case .report:
            let vc = SEExamineListViewController(type: .seneAIReport)
            // AI报告状态为
            vc.sendHandler = { vm in
                self.viewModel.checkReport = SEChatCheckReport(id: vm.model.id,
                                                               name: vm.model.name,
                                                               time: vm.model.checkScheduleTime,
                                                               list: vm.checkItemNamesArray,
                                                               checkHosId: vm.model.checkHosId,
                                                               reportTitle: vm.reportTitle,
                                                               status: vm.model.aiStatus)
                self.messageType = .checkReport
                self.generateMessageId()
            }
            navigationController?.pushViewController(vc, animated: true)
        }
    }
    
    private func openPhotoLibrary() {
        UIScrollView.appearance().contentInsetAdjustmentBehavior = .automatic
        let imagePicker = UIImagePickerController()
        imagePicker.delegate = self
        imagePicker.sourceType = .photoLibrary
        imagePicker.modalPresentationStyle = .custom
        present(imagePicker, animated: true, completion: nil)
    }
    
    private func checkCameraPermission() {
        let authStatus = AVCaptureDevice.authorizationStatus(for: .video)
        switch authStatus {
        case .notDetermined:
            AVCaptureDevice.requestAccess(for: .video) { (granted) in
                if !granted {
                    dispatch_async_safely_main_queue {
                        SEAlert.show(in: self.navigationController,
                                     title: "无法访问您的相机",
                                     message: "请到设置 -> 隐私 -> 相机 ，打开访问权限",
                                     confirmTitle: "去设置") { _ in
                            SEOpenSettingURL()
                        }
                    }
                }
            }
        case .restricted, .denied:
            SEAlert.show(in: self.navigationController,
                         title: "无法访问您的相机",
                         message: "请到设置 -> 隐私 -> 相机 ，打开访问权限",
                         confirmTitle: "去设置") { _ in
                SEOpenSettingURL()
            }
        case .authorized:
            openCamera()
        default:
            break
        }
    }
    
    private func openCamera() {
        let imagePicker = UIImagePickerController()
        imagePicker.delegate = self
        imagePicker.sourceType = .camera
        present(imagePicker, animated: true, completion: nil)
    }
}

// MARK: - UIImagePickerControllerDelegate

extension SEChatViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        if let image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage {
            sendImage = image
            messageType = .image
            generateMessageId()
        }
        dismiss(animated: true) {
            UIScrollView.appearance().contentInsetAdjustmentBehavior = .never
        }
    }
}

// MARK: - UITextViewDelegate

extension SEChatViewController: UITextViewDelegate {
    func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
        if text == "\n" {
            checkSendTextEnable()
            return false
        }
        return true
    }
    
    func textViewDidChange(_ textView: UITextView) {
        let contentHeight = textView.contentSize.height
        guard contentHeight < kChatActionBarTextViewMaxHeight else { return }
        chatActionBarView.inputTextViewCurrentHeight = contentHeight + 17
        controlExpandableInputView(showExpandable: true)
    }
    
    func textViewShouldBeginEditing(_ textView: UITextView) -> Bool {
        chatActionBarView.inputTextViewCallKeyboard()
        
        // 使 UITextView 滚动到末尾的区域
        UIView.setAnimationsEnabled(false)
        let range = NSMakeRange(textView.text.count - 1, 1)
        textView.scrollRangeToVisible(range)
        UIView.setAnimationsEnabled(true)
        return true
    }
}
